//
//					Frame.h
// A "stupid" widget which only can to contain others

#ifndef __NEWA_FRAME_H
#define __NEWA_FRAME_H

#pragma message( "INCLUDING FILE: " __FILE__ )

#include "Widget.h"
#include "WidgetElement.h"
#include "WidgetStyle.h"
#include "Layout.h"
#include "Disposals.h"

namespace newa
{
	class Frame : public Widget
	{
	public:
		Frame()
		{
			m_element = WidgetElement::create( _T("frame") );
			m_element->OnPaint = EventTraits< EVPAINT >::HandlerFtor ( this, &Frame::paint );
		}

		void rect( const Rect& r )
		{
			m_element->rect( r );
		}

		Rect rect() const
		{
			return m_element->rect();
		}

		const WidgetElementRef site() const
		{
			return m_element;
		}

		WidgetElementRef elem()
		{
			return m_element;
		}


	protected:

		virtual void paint( PixBuf * pb)
		{
			styleMan().style().paintFrame( *this, *pb );
		}

	private:
		WidgetElementRef m_element;
	};

	class FrameWithHeader : public Widget
	{
	public:

		FrameWithHeader()
			: m_mspos( -1, -1 )
		{
			m_frame = WidgetElement::create( _T("FrameWithHeader::frame") );

			m_header = WidgetElement::create( _T("FrameWithHeader::header") );
			m_header->OnPaint = EventTraits< EVPAINT >::HandlerFtor ( this, &FrameWithHeader::paintHeader );
			m_clientarea = WidgetElement::create( _T("FrameWithHeader::client_area") );
			m_clientarea->OnPaint = EventTraits< EVPAINT >::HandlerFtor ( this, &FrameWithHeader::paintClientArea );

			m_header->OnLMouseDown = EventTraits< EVLMSDOWN >::HandlerFtor( this, &FrameWithHeader::onLMouseDown );
			m_header->OnLMouseUp = EventTraits< EVLMSUP >::HandlerFtor( this, &FrameWithHeader::onLMouseUp );
			m_header->OnMouseMove = EventTraits< EVLMSUP >::HandlerFtor( this, &FrameWithHeader::onMouseMove );

			Settle< Disposals::WinLessee >( m_header, m_frame );
			Settle< Disposals::WinLessee >( m_clientarea, m_frame );

			m_layout.listen( *m_frame );
			m_layout.manage( *m_header, 0 );
			m_layout.manage( *m_clientarea, 1 );
		}

		void rect( const Rect& r )
		{
			m_frame->rect( r );
		}

		Rect rect() const
		{
			return m_frame->rect();
		}

		WidgetElementRef site()
		{
			return m_clientarea;
		}

		WidgetElementRef elem()
		{
			return m_frame;
		}

		WidgetElementRef header() const
		{
			return m_header;
		}

		WidgetElementRef clientArea() const
		{
			return m_clientarea;
		}

	protected:

		virtual void paintHeader( PixBuf * pb)
		{
			styleMan().style().paintFrameHeader( *this, *pb );
		}

		virtual void paintClientArea( PixBuf * pb)
		{
			styleMan().style().paintFrameClientArea( *this, *pb );
		}

	private:

		WidgetElementRef m_frame;
		WidgetElementRef m_header;
		WidgetElementRef m_clientarea;

		class LayoutHeader : public LayoutManager
		{
		private:
			static const int HEADER_HEIGHT = 24;

			virtual void doLayout( const Rect& r )
			{
				SmallRect * Header = managable( 0 );
				SmallRect * ClientArea = managable( 1 );

				if( Header == 0 || ClientArea == 0 )
					return;
				
				Header->smallRect
					( Rect (
						r.x, 
						r.y, 
						r.width, 
						HEADER_HEIGHT
					));

				ClientArea->smallRect
					( Rect (
						r.x,
						r.y + HEADER_HEIGHT,
						r.width, 
						r.height - HEADER_HEIGHT
					));
			}
		};

		LayoutHeader m_layout;


		Point m_mspos;
		Point m_winpos;

		void onLMouseDown( const MouseState&, int x, int y )
		{
			m_mspos = Point( x, y );
			m_winpos = m_frame->rect().pos();
			m_header->captureMouse();
		}

		void onLMouseUp( const MouseState&, int x, int y )
		{
			m_mspos = Point( -1, -1 );
			m_header->releaseMouse();
		}

		void onMouseMove( const MouseState&, int x, int y )
		{
			Rect r = m_header->rect();

			if( m_mspos.x >= 0 ) {
				x += - m_mspos.x + m_winpos.x;
				y += - m_mspos.y + m_winpos.y;
				MoveItemRectTo( *m_frame, x , y  );
				//m_frame->repaint();
				//m_frame->rect( Rect( m_frame->rect().pos(), m_frame->rect().size() ) );
			}
		}
	};

	typedef Loki::SmartPtr< FrameWithHeader > FrameWithHeaderPtr;

	typedef Loki::SmartPtr< Frame > FramePtr;
}

#endif
